package com.by.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.by.entity.ShopCartItem;
import com.by.entity.dto.UpdateItemNumberDto;
import com.by.entity.vo.ShopCartItemVo;
import com.by.mapper.LiGoodsMapper;
import com.by.mapper.ShopCartItemMapper;
import com.by.service.ShopCartItemService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * 购物车(ShopCartItem)表服务实现类
 *
 * @author makejava
 * @since 2025-04-11 14:42:31
 */
@Service("shopCartItemService")
@Slf4j
public class ShopCartItemServiceImpl extends ServiceImpl<ShopCartItemMapper, ShopCartItem> implements ShopCartItemService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private LiGoodsMapper liGoodsMapper;

    @Autowired
    private ShopCartItemMapper shopCartItemMapper;


    private final String HALF_CACHE_KEY = "cart";

    @Override
    public List querryAll() {
        List list =new ArrayList<>();
        String userId= "1";
        String key = HALF_CACHE_KEY + userId;
        BoundHashOperations<String, Object, Object> boundHashOps = redisTemplate.boundHashOps(key);
        Map<Object, Object> entries = boundHashOps.entries();
        if (entries.isEmpty()) {
            // 查询数据库返回基本数据
            List<ShopCartItem> itemList = super.query().eq("user_id", userId).list();
            // 获取购物车中商品的id
            List<Long> itemIdList = itemList.stream().map(ShopCartItem::getSkuId).collect(Collectors.toList());
            Map<Object, Object> map =new HashMap<>();
            liGoodsMapper.selectBatchIds(itemIdList).forEach(liGoods -> {
                map.put(liGoods.getId(), liGoods.getPrice());
            });
            if (itemList != null) {
                // 将查询到的ShopCartItem数据复制到为ShopCartItemVo对象
                List<ShopCartItemVo> ShopCartItemVoList = itemList.stream()
                        .map(item -> {
                            ShopCartItemVo shopCartItemVo = new ShopCartItemVo();
                            // 获取单价
                            shopCartItemVo.setSingleProductPrice((Double) map.get(item.getSkuId()));
                            // 获取单个商品总价
                            shopCartItemVo.setItemTotalPrice((Double)map.get(item.getSkuId()) * item.getCount());
                            BeanUtil.copyProperties(item, shopCartItemVo);
                            return shopCartItemVo;
                        })
                        .collect(Collectors.toList());
                itemIdList.forEach(itemId -> {
                    ShopCartItemVoList.forEach(shopCartItemVo -> {
                        boundHashOps.put(itemId.toString(), JSONUtil.toJsonStr(shopCartItemVo));
                    });
                });

                return ShopCartItemVoList;
            } else {
                log.info("查询数据库失败");
            }
        }
        entries.forEach((k, v) -> {
            list.add( JSONUtil.toBean((String) v, ShopCartItemVo.class));
        });
        return list;
    }

    @Override
    public Boolean updateNumber(UpdateItemNumberDto updateItemNumberDto)  {

        String userId= "1";
        String key = HALF_CACHE_KEY + userId;
        BoundHashOperations<String, Object, Object> boundHashOps = redisTemplate.boundHashOps(key);
        ShopCartItemVo shopCartItemVo = JSONUtil.toBean((String) boundHashOps.get(key), ShopCartItemVo.class);
        Integer quantity = shopCartItemVo.getCount();
        if (quantity < updateItemNumberDto.getCount()){
            return false;
        }
        Integer isChecked = updateItemNumberDto.getIsChecked();
        Integer count = updateItemNumberDto.getCount();
        if (isChecked != null){
            shopCartItemVo.setIsChecked(isChecked);
        }
        if (count.equals(quantity)){
            shopCartItemVo.setCount(count);
        }
        boundHashOps.put(key, JSONUtil.toJsonStr(shopCartItemVo));
        return true;
    }

    @Override
    public Boolean removeByCartId(Integer cartItemId) {
        // 延迟双删
        // 1.删除旧缓存
        String userId= "1";
        String key = HALF_CACHE_KEY + userId;
        redisTemplate.delete(key);
        // 2.更新数据库
        boolean b = super.removeById(cartItemId);
        if (!b) {
            return false;
        }
        // 3.再次删除缓存
        new Thread(() -> {
            try {
                Thread.sleep(3000);
                redisTemplate.delete(key);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }).start();
        return true;
    }

    @Override
    public Boolean addCartItem(ShopCartItem shopCartItem) {
        String userId= "1";
        String key = HALF_CACHE_KEY + userId;
        BoundHashOperations<String, Object, Object> hashOps = redisTemplate.boundHashOps(key);
        Object o = hashOps.get(shopCartItem.getSkuId());
        if (o == null) {
            // 第一次添加
            ShopCartItemVo shopCartItemVo = new ShopCartItemVo();
            BeanUtil.copyProperties(shopCartItem, shopCartItemVo);
            Double price = liGoodsMapper.selectById(shopCartItem.getSkuId()).getPrice();
            shopCartItemVo.setSingleProductPrice(price);
            hashOps.put(shopCartItem.getSkuId(), JSONUtil.toJsonStr(shopCartItemVo));
        }
        // 不是第一次添加
        ShopCartItemVo shopCartItemVo = JSONUtil.toBean((String) o, ShopCartItemVo.class);
        shopCartItemVo.setCount(shopCartItemVo.getCount() + shopCartItem.getCount());
        hashOps.put(shopCartItem.getSkuId(), JSONUtil.toJsonStr(shopCartItemVo));
        return true;
    }
}
